from flask import Blueprint, render_template, flash, redirect, url_for, jsonify, request, current_app, send_from_directory
from marshmallow.exceptions import ValidationError
from werkzeug.security import generate_password_hash, check_password_hash
from flask_jwt_extended import create_access_token, jwt_required, create_refresh_token, jwt_refresh_token_required, get_jwt_identity, fresh_jwt_required
from datetime import datetime
from application.api.users.schemas import *
from application.common.file_helper import *
from application.common.error_helper import *


# 生成蓝图对象
api_users = Blueprint('api_users', __name__)


# 新增用户
@api_users.route('/', methods=['POST'])
def add_user():
    json_data = request.get_json()
    user = Users.query.filter_by(mobile=json_data['mobile']).first()
    # 判断手机号是否注册过
    if user is not None:
        return jsonify({'code': USER_MOBILE_ERROR[0], 'message': USER_MOBILE_ERROR[1], 'data': {'mobile': json_data['mobile']}})
    json_data['password'] = generate_password_hash(json_data['password'])

    users_schema = UsersSchema()
    # 这句话在非法输入会报错 ValidationError
    try:
        user = users_schema.load(json_data)
        user_type = json_data['user_type']
        if user_type == 2:
            user.user_poll = 5
        else:
            user.user_poll = 0
        db.session.add(user)
        db.session.commit()
        return jsonify({'code': USER_REGISTER_SUCCESS[0], 'message': USER_REGISTER_SUCCESS[1], 'data': {'user_id': user.id}})
    except ValidationError:
        return jsonify({'code': 8001, 'message': '创建失败，请检查字段是否填写完整'})


# 登录
@api_users.route('/login', methods=['POST'])
def login():
    json_data = request.get_json()
    user_schema = UsersSchema()
    user_schema.load(json_data, partial=('mobile', 'user_type',))
    name = json_data['name']
    user = Users.query.filter_by(name=name).first()
    if user is None:
        return jsonify({'code': USER_LOGIN_ERROR[0], 'message': USER_LOGIN_ERROR[1]})
    if check_password_hash(user.password, json_data['password']):
        # 验证通过，分配jwt令牌，生成一个新鲜的令牌
        jwt_token = create_access_token(identity=name, fresh=True)
        # 生成一个刷新用的token
        refresh_token = create_refresh_token(identity=name)
        return jsonify({'code': TOKEN_SUCCESS[0], 'message': TOKEN_SUCCESS[1], 'token': jwt_token, 'refresh_token': refresh_token})
    return jsonify({'code': USER_LOGIN_ERROR[0], 'message': USER_LOGIN_ERROR[1]})

# 刷新token值
@api_users.route('/refresh', methods=['POST'])
@jwt_refresh_token_required
def refresh():
    # 取到用户名
    current_user = get_jwt_identity()
    # 取用户的状态，如果停用就不生成token
    user = Users.query.filter_by(name=current_user).first()
    if user is not None and user.status == 1:
        result = {
            'code': TOKEN_SUCCESS[0], 'message': TOKEN_SUCCESS[1],
            'access_token': create_access_token(identity=current_user, fresh=False)
        }
        return jsonify(result)
    return jsonify({'code': TOKEN_ERROR[0], 'message': TOKEN_ERROR[1]})

# 上传图像的接口
@api_users.route('/avatar/<int:user_id>', methods=['POST'])
# @jwt_required
def upload_product(user_id):
    user = Users.query.get(user_id)
    # 判断用户类型
    if user.user_type != 1:
        return jsonify({'code': NOT_HAVE_PERMIT[0], 'message': NOT_HAVE_PERMIT[1]})
    product_name = request.form.get('product_name')
    product = Product.query.filter_by(name=product_name).first()
    # 看名字是否重复
    if product:
        return jsonify({'code': NAME_IS_EXIST[0], 'message': NAME_IS_EXIST[1]})
    file = request.files.get('avatar')
    # 检查文件类型，必须是图片
    if not is_allowed_image(file.content_type):
        return jsonify({'code': UPLOAD_IMAGE_TYPE_ERROR[0], 'message': UPLOAD_IMAGE_TYPE_ERROR[1]})
    # 生成文件名和文件路径
    # 后缀
    ext = file.filename.split('.')[-1]
    # 前缀
    filename = generate_filename()
    full_filename = filename + '.' + ext
    print(full_filename)
    if user.product_id != None:
        product = Product.query.get(user.product_id)
        # 取到项目文件夹
        root_path = get_root_path(current_app)
        # UPLOAD_PATH = 'upload' 拼接绝对路径
        filepath = os.path.join(root_path, current_app.config['UPLOAD_PATH'])
        # 删除用户之前的作品
        os.remove(os.path.join(filepath, product.product_addr))
        # 更改新作品的信息
        product.name = product_name
        product.product_addr = full_filename
        product.upload_time = datetime.now()
        db.session.add(product)
        db.session.commit()
        # 保存新文件
        filepath = current_app.config['UPLOAD_PATH']
        file.save(os.path.join(filepath, full_filename))
        # 返回数据
        return jsonify({'code': UPLOAD_IMAGE_SUCCESS[0], 'message': UPLOAD_IMAGE_SUCCESS[1]})
    # 用户之前没有上传作品记录就新建记录
    product = Product()
    product.name = product_name
    product.product_addr = full_filename
    product.upload_time = datetime.now()
    db.session.add(product)
    db.session.commit()
    product = Product.query.filter_by(name=product_name).first()
    user = Users.query.get(user_id)
    user.product_id = product.id
    db.session.add(user)
    db.session.commit()
    # 找到根目录
    filepath = current_app.config['UPLOAD_PATH']
    # 在图片文件下新建文件
    file.save(os.path.join(filepath, full_filename))
    return jsonify({'code': UPLOAD_IMAGE_SUCCESS[0], 'message': UPLOAD_IMAGE_SUCCESS[1]})
